package com.mlick.a.java8.juc;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author lixiangxin
 * @date 2019/4/29 10:23
 **/
@Slf4j
public class MultipleThreadCountDownKit {

  AtomicInteger atomicInteger;

  private final Object notify;


  public MultipleThreadCountDownKit(int num) {
    this.atomicInteger = new AtomicInteger(num);
    this.notify = new Object();
  }


  public void count() {

    if (atomicInteger.get() <= 0) {
      return;
    }

    int count = atomicInteger.decrementAndGet();

    if (count == 0) {
      synchronized (notify) {
        notify.notifyAll();
      }
    }
  }


  public void await() throws InterruptedException {
    synchronized (notify) {
      while (atomicInteger.get() > 0) {
        log.debug("wait...");
        notify.wait();
      }
    }
  }


  public static void main(String[] args) throws InterruptedException {

    MultipleThreadCountDownKit multipleThreadCountDownKit = new MultipleThreadCountDownKit(3);

    Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {

        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }

        multipleThreadCountDownKit.count();
        log.info("Thread Name==>" + Thread.currentThread().getName());
      }
    });
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        multipleThreadCountDownKit.count();
        log.info("Thread Name==>" + Thread.currentThread().getName());
      }
    });
    Thread t3 = new Thread(new Runnable() {
      @Override
      public void run() {

        try {
          Thread.sleep(5000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        multipleThreadCountDownKit.count();
        log.info("Thread Name==>" + Thread.currentThread().getName());
      }
    });

    t1.start();
    t2.start();
    t3.start();

    multipleThreadCountDownKit.await();

    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    log.info("finish All Threads");
  }

}
